package com.ff.kvm.mall.service.impl;

import com.ff.kvm.common.dv.es.GiftBoxESDV;
import com.ff.kvm.common.dv.gift.GiftBoxDV;
import com.ff.kvm.common.dv.gift.GiftBoxItemsDV;
import com.ff.kvm.common.dv.product.*;
import com.ff.kvm.common.dv.shopping.CheckOrderResultDV;
import com.ff.kvm.common.dv.shopping.ItemsDV;
import com.ff.kvm.common.eunm.OrderTypeEnum;
import com.ff.kvm.common.eunm.ProductTypeEnum;
import com.ff.kvm.common.eunm.StatusEnum;
import com.ff.kvm.common.util.Constants;
import com.ff.kvm.common.util.ConvertUtil;
import com.ff.kvm.common.util.MyUtil;
import com.ff.kvm.common.vo.PageResult;
import com.ff.kvm.common.vo.Response;
import com.ff.kvm.dao.mapper.OrderItemsMapper;
import com.ff.kvm.dao.mapper.OrderPriceMapper;
import com.ff.kvm.dao.mapper.PersonalGiftMapper;
import com.ff.kvm.dao.mapper.ProductMapper;
import com.ff.kvm.dao.model.*;
import com.ff.kvm.dao.model.po.GiftPostage;
import com.ff.kvm.mall.service.*;
import com.ff.kvm.team.consumer.TeamConsumer;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemsService orderItemsService;

    @Autowired
    private OrderItemsMapper orderItemsMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderPriceService orderPriceService;

    @Autowired
    private OrderPriceMapper orderPriceMapper;

    @Autowired
    private ProductPartitionService productPartitionService;

    @Autowired
    private PersonalGiftMapper personalGiftMapper;

    @Autowired
    private ProductRobService productRobService;

    @Autowired
    private ProductHotService productHotService;

    @Autowired
    private TeamConsumer teamConsumer;
    @Autowired
    private SignInService signInService;

    @Override
    public Product findProductById(int productId) {
        return productMapper.selectByPrimaryKey(productId);
    }

    @Override
    public Response<PageResult<ProductDV>> productList(ProductPageDV productPageDV) {

        Response<PageResult<ProductDV>> response = new Response<>();
        PageResult<ProductDV> result = new PageResult<>();
        double discount = 1D;
        if (productPageDV.isDiscount()) {
            int lv = userService.getUserLvByUserId(productPageDV.getUserId());
            discount = Double.valueOf(redisService.getCache(Constants.GIFT_BOX_LV + lv).split("-")[1]);
        } else {
            discount = Double.valueOf(redisService.getCache(Constants.GIFT_BOX_LV + 0).split("-")[1]);
        }

        int pageSize = Integer.valueOf(redisService.getCache(Constants.PAGE_SIZE));
        List<ProductDV> listDV = new ArrayList<>();
        Page page = PageHelper.startPage(productPageDV.getPageNum(), pageSize);
        List<Product> list = productMapper.findProductList(productPageDV.getCategory(), productPageDV.getType());
        for (Product product : list) {
            ProductDV productDV = new ProductDV();
            productDV.setId(product.getId());
            productDV.setName(product.getName());
            List<String> imgs = ConvertUtil.jsonToList(product.getImg(), String.class);
            if (!MyUtil.isEmpty(imgs)) {
                productDV.setIcon(imgs.get(0));
            }
            productDV.setPrice(product.getPrice());
            productDV.setCurrentPrice(MyUtil.float2(product.getPrice() * discount));
            productDV.setMonthSale(product.getMonthSale());
            productDV.setRemark(product.getRemark());
            productDV.setStock(product.getStock());
            listDV.add(productDV);
        }
        result.setData(listDV);
        result.setPageSize(pageSize);
        result.setTotal(page.getTotal());
        response.setData(result);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Response<ProductDetailDV> productDetail(int userId, int id) {

        Response<ProductDetailDV> response = new Response<>();
        int lv = userService.getUserLvByUserId(userId);

        Product product = productMapper.selectByPrimaryKey(id);
        ProductDetailDV productDetailDV = ConvertUtil.convert(product, ProductDetailDV.class);
        if (product.getType() == ProductTypeEnum.PRODUCT.type()) {
            double discount = Double.valueOf(redisService.getCache(Constants.GIFT_BOX_LV + lv).split("-")[1]);
            productDetailDV.setCurrentPrice(MyUtil.float2(product.getPrice() * discount));
        } else if (product.getType() == ProductTypeEnum.ROB.type()) {
            ProductRob productRob = productRobService.findProductRob(product.getId());
            productDetailDV.setStartTime(MyUtil.formatDateYMDhms(productRob.getStartTime()));
            productDetailDV.setEndTime(MyUtil.formatDateYMDhms(productRob.getEndTime()));
            productDetailDV.setCurrentPrice(productRob.getPriceRob());
            productDetailDV.setStock(productRob.getNum());
        } else if (product.getType() == ProductTypeEnum.HOT.type()) {
            ProductHot productHot = productHotService.findProductHot(product.getId());
            productDetailDV.setCurrentPrice(productHot.getPriceHot());
        }
        productDetailDV.setImgs(ConvertUtil.jsonToList(product.getImg(), String.class));
        response.setData(productDetailDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public synchronized Response<CheckOrderResultDV> buyProduct(BuyProductDV buyProductDV) {
        Response<CheckOrderResultDV> response = new Response<>();
        if(buyProductDV.getQuantity() <= 0){
            response.setCode(StatusEnum.FAIL.code());
            response.setMsg(StatusEnum.FAIL.description());
            return response;
        }
        double discount = 1D;
        Product product = productMapper.findProductNormal(buyProductDV.getId());
        int qty = buyProductDV.getQuantity();
        //礼包不打折，数量为1
        int type = 0;
        double amount = product.getPrice();
        int lv = userService.getUserLvByUserId(buyProductDV.getUserId());
        if (product.getType() == ProductTypeEnum.PRODUCT.type()) {
            if (product.getStock() <= 0) {
                response.setCode(StatusEnum.STOCK_NOT_ENOUGH.code());
                response.setMsg(StatusEnum.STOCK_NOT_ENOUGH.description());
                return response;
            }
            discount = Double.valueOf(redisService.getCache(Constants.GIFT_BOX_LV + lv).split("-")[1]);
            //计算打折后的金额
            amount = MyUtil.float2(product.getPrice() * buyProductDV.getQuantity() * discount);
            type = OrderTypeEnum.NORMAL.type();
        } else if (product.getType() == ProductTypeEnum.GIFT_BOX.type()) {
            qty = 1;
            type = OrderTypeEnum.GIFTBOX.type();
            if (product.getLv() <= lv) {
                response.setCode(StatusEnum.NOT_BUY_GIFT_BOX.code());
                response.setMsg(StatusEnum.NOT_BUY_GIFT_BOX.description());
                return response;
            }
        } else if (product.getType() == ProductTypeEnum.ROB.type()) {
            ProductRob productRob = productRobService.findProductRob(product.getId());
            if (productRob.getNum() <= 0) {
                response.setCode(StatusEnum.STOCK_NOT_ENOUGH.code());
                response.setMsg(StatusEnum.STOCK_NOT_ENOUGH.description());
                return response;
            }
            amount = productRob.getPriceRob();
            type = OrderTypeEnum.ROB.type();

        } else if (product.getType() == ProductTypeEnum.HOT.type()) {
            ProductHot productHot = productHotService.findProductHot(product.getId());
            type = OrderTypeEnum.HOT.type();
            amount = productHot.getPriceHot();
        }
        Order order = orderService.createOrder(buyProductDV.getUserId(), buyProductDV.getAddressId(), buyProductDV.getExpressType(), buyProductDV.getRemark(), type);

        orderItemsService.createOrderItems(order.getId(), new ItemsDV(buyProductDV.getId(), qty), discount, amount);

        //存储价格打折信息
        orderPriceService.saveOrderPrice(order.getId(), discount, amount, product.getPostFee());

        //抢购商品需要扣减库存
        if (product.getType() == ProductTypeEnum.ROB.type()) {
            productRobService.updateStock(product.getId(),buyProductDV.getQuantity());
        }
        CheckOrderResultDV checkOrderResultDV = new CheckOrderResultDV();
        checkOrderResultDV.setOrderId(order.getId());
        checkOrderResultDV.setOrderNO(order.getNo());
        response.setData(checkOrderResultDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Transactional
    @Override
    public Response<CheckOrderResultDV> buySigninGiftProduct(BuyProductDV buyProductDV) {
        Response<CheckOrderResultDV> response = new Response();
        GiftPostage personalGift = personalGiftMapper.getGiftPostage(buyProductDV.getId());
        //获取礼物邮费
        Double postFee = personalGift.getPostage();
        //生成订单
        Order order = orderService.createOrder(buyProductDV.getUserId(), buyProductDV.getAddressId(), buyProductDV.getExpressType(), buyProductDV.getRemark(), OrderTypeEnum.SIGIN.getType());
        //生成订单商品信息
        OrderItems orderItems = new OrderItems();
        orderItems.setCreateTime(new Date());
        orderItems.setOrderId(order.getId());
        orderItems.setProductNo(order.getNo());
        orderItems.setProductId(personalGift.getProductId());
        orderItems.setQuantity(1);
        orderItems.setPrice(0D);
        orderItemsMapper.insert(orderItems);
        //生成订单价格信息
        OrderPrice orderPrice = new OrderPrice();
        orderPrice.setCreateTime(new Date());
        orderPrice.setOrderId(order.getId());
        orderPrice.setDiscount(1D);
        orderPrice.setDiscountAmount(0D);
        orderPrice.setAmount(0D);
        orderPrice.setPostFee(postFee);
        orderPrice.setTotal(postFee);
        orderPriceMapper.insert(orderPrice);
        //礼品状态设置
        signInService.getGift(buyProductDV.getUserId(), buyProductDV.getId());
        //return info
        CheckOrderResultDV checkOrderResultDV = new CheckOrderResultDV();
        checkOrderResultDV.setOrderId(order.getId());
        checkOrderResultDV.setOrderNO(order.getNo());
        response.setData(checkOrderResultDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Response<List<GiftBoxDV>> giftBoxList() {
        List<GiftBoxDV> listDV = new ArrayList<>();
        List<Product> list = productMapper.findGiftBox();
        for (Product product : list) {
            GiftBoxDV giftBoxDV = new GiftBoxDV();
            giftBoxDV.setId(product.getId());
            giftBoxDV.setName(product.getName());
            giftBoxDV.setPrice(MyUtil.float2(product.getPrice() + product.getPostFee()));
            giftBoxDV.setDiscount(product.getDiscount());
            giftBoxDV.setRemark(product.getRemark());
            giftBoxDV.setDetail(product.getDetail());
            giftBoxDV.setItems(ConvertUtil.jsonToList(product.getItems(), GiftBoxItemsDV.class));
            listDV.add(giftBoxDV);
        }

        Response<List<GiftBoxDV>> response = new Response<>();
        response.setData(listDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Response<List<GiftBoxItemsDV>> giftBoxItems(int id) {
        Response<List<GiftBoxItemsDV>> response = new Response<>();
        Product product = productMapper.selectByPrimaryKey(id);
        response.setData(ConvertUtil.jsonToList(product.getItems(), GiftBoxItemsDV.class));
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public double getPriceById(Integer productId) {

        return productMapper.getPriceById(productId);
    }

    @Override
    public List<Product> findProductTopByType(int type) {
        return productMapper.findProductTopByType(type);
    }

    @Override
    public List<Product> findProductSpecialTop() {
        return productMapper.findProductSpecialTop();
    }

    @Override
    public List<Product> findProductTopByCategory(int category) {
        return productMapper.findProductTopByCategory(category);
    }

    @Override
    public Product findProductByIdForCheckOrder(int productId) {
        return productMapper.findProductByIdForCheckOrder(productId);
    }

    @Override
    public Response<List<CategoryDV>> categoryList() {
        Response<List<CategoryDV>> response = new Response<>();
        List<CategoryDV> listDV = new ArrayList<>();
        List<ProductPartition> list = productPartitionService.findProductPartition();
        for (ProductPartition productPartition : list) {
            CategoryDV categoryDV = new CategoryDV();
            categoryDV.setId(productPartition.getId());
            categoryDV.setName(productPartition.getName());
            categoryDV.setBackGroundImg(productPartition.getBackGroundImg());
            listDV.add(categoryDV);
        }
        response.setData(listDV);
        response.setCode(StatusEnum.SUCCESS.code());
        response.setMsg(StatusEnum.SUCCESS.description());
        return response;
    }

    @Override
    public Product findProductNormal(int productId) {
        return productMapper.findProductNormal(productId);
    }

    @Override
    public void sendGiftBoxES(int userId, int orderId, Product product) {
        GiftBoxESDV giftBoxESDV = new GiftBoxESDV();
        giftBoxESDV.setUserId(userId);
        giftBoxESDV.setOrderId(orderId);
        giftBoxESDV.setLv(product.getLv());
        giftBoxESDV.setPostFee(product.getPostFee());
        giftBoxESDV.setTotal(product.getPrice());
        giftBoxESDV.setCreateTime(new Date());
        teamConsumer.addGiftBox(giftBoxESDV);
    }

    @Override
    public Product findProductNormalByOrderId(int orderId) {
        return productMapper.findProductNormalByOrderId(orderId);
    }

    @Override
    public String getGiftItemsByOrderId(int orderId) {
        return productMapper.getGiftItemsByOrderId(orderId);
    }

    @Override
    public String getGiftNameByOrderId(int orderId) {

        return productMapper.getGiftNameByOrderId(orderId);
    }
}
